package com.wtb.javatool.service.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wtb.javatool.dao.AssetsMapper;
import com.wtb.javatool.dao.CatalogMapper;
import com.wtb.javatool.dao.CourseMapper;
import com.wtb.javatool.entity.Assets;
import com.wtb.javatool.entity.Catalog;
import com.wtb.javatool.exception.EvaluationException;
import com.wtb.javatool.service.CatalogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CatalogServiceImpl extends ServiceImpl<CatalogMapper, Catalog> implements CatalogService {

    @Autowired
    private CatalogMapper catalogDao;
    @Autowired
    private AssetsMapper assetsMapper;


//    @Override
//    public List<Catalog> getCatalogAndAssetsByBandId(Long bandId) throws EvaluationException {
//        try {
//            //catalogs是根据order以及level升序排序的目录list
//            List<Catalog> catalogs = catalogDao.getCatalogByBandId(bandId);
//            if (catalogs.isEmpty()) {
//                return Collections.emptyList();
//            }
//            //找出根目录
//            List<Catalog> rootCatalogs = catalogs.stream()
//                    .filter(catalog -> catalog.getParentId() == null && catalog.getLevel() == 1)
//                    .collect(Collectors.toList());
//
//            //找出子目录
//            List<Catalog> childCatalogs = catalogs.stream()
//                    .filter(catalog -> catalog.getParentId() != null)
//                    .collect(Collectors.toList());
//
//            //构建树
//            buildCatalogTree(rootCatalogs, childCatalogs);
//
//            //返回构建好的根目录
//            return rootCatalogs;
//        } catch (Exception e) {
//            throw new EvaluationException("获取目录失败", e);
//        }
//    }
//
//    private void buildCatalogTree(List<Catalog> rootCatalogs, List<Catalog> childCatalogs) {
//        for (Catalog catalog : rootCatalogs) {
//            List<Catalog> children = findChildren(childCatalogs, catalog.getId());
//            if (children.isEmpty()) {
//                continue;
//            }
//            catalog.setChildCatalog(children); // 设置子目录
//            buildCatalogTree(children, childCatalogs); // 传递的是子目录的子目录列表
//        }
//    }
//
//
//    private List<Catalog> findChildren(List<Catalog> catalogs, Long parentId) {
//        return catalogs.stream()
//                .filter(catalog -> catalog.getParentId() != null && catalog.getParentId().equals(parentId))
//                .collect(Collectors.toList());
//    }


//    @Override
//    public List<Catalog> getCatalogAndAssetsByBandId(Long bandId) throws EvaluationException {
//        try {
//            //catalogs是根据order以及level升序排序的目录list
//            List<Catalog> catalogs = catalogDao.getCatalogByBandId(bandId);
//            if (catalogs.isEmpty()) {
//                return Collections.emptyList();
//            }
//
//            // 使用Map来存储每个父目录的子目录
//            Map<Long, List<Catalog>> childMap = new HashMap<>();
//            for (Catalog catalog : catalogs) {
//                Long parentId = catalog.getParentId();
//                if (parentId != null) {
//                    childMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(catalog);
//                }
//            }
//
//            // 找出根目录并构建树
//            List<Catalog> rootCatalogs = catalogs.stream()
//                    .filter(catalog -> catalog.getParentId() == null && catalog.getLevel() == 1)
//                    .peek(root -> setChildren(root, childMap)) // 设置子目录并递归处理子目录
//                    .collect(Collectors.toList());
//
//            return rootCatalogs;
//        } catch (Exception e) {
//            throw new EvaluationException("获取目录失败", e);
//        }
//    }
//
//    private void setChildren(Catalog catalog, Map<Long, List<Catalog>> childMap) {
//        List<Catalog> children = childMap.getOrDefault(catalog.getId(), Collections.emptyList());
//        catalog.setChildCatalog(children);
//        for (Catalog child : children) {
//            setChildren(child, childMap); // 递归设置子目录的子目录
//        }
//    }

    @Override
    public List<Catalog> getCatalogAndAssetsByBandId(Long bandId, Long schoolId) throws EvaluationException {
        try {
            // assets是根据目录的order以及level以及自己的level升序排序的资源list
            List<Assets> assets = assetsMapper.getAssetsByBandId(bandId);
            // catalogs是根据order以及level升序排序的目录list
            List<Catalog> catalogs = catalogDao.getCatalogByBandId(bandId,schoolId);

            if (catalogs.isEmpty()) {
                return Collections.emptyList();
            }

            // 使用Map来存储每个父目录的子目录
            Map<Long, List<Catalog>> childMap = new HashMap<>();
            for (Catalog catalog : catalogs) {
                Long parentId = catalog.getParentId();
                if (parentId != null) {
                    childMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(catalog);
                }
            }

            // 创建一个Map来存储每个目录的Assets列表
            Map<Long, List<Assets>> assetsMap = new HashMap<>();
            for (Assets asset : assets) {
                Long catalogId = asset.getCatalogId();
                assetsMap.computeIfAbsent(catalogId, k -> new ArrayList<>()).add(asset);
            }

            // 找出根目录并构建树，同时分配Assets
            List<Catalog> rootCatalogs = buildCatalogTreeWithAssets(catalogs, childMap, assetsMap);

            return rootCatalogs;
        } catch (Exception e) {
            throw new EvaluationException("获取目录和资源失败", e);
        }
    }

    private List<Catalog> buildCatalogTreeWithAssets(List<Catalog> catalogs, Map<Long, List<Catalog>> childMap, Map<Long, List<Assets>> assetsMap) {
        return catalogs.stream()
                .filter(catalog -> catalog.getParentId() == null)
                .peek(root -> {
                    setChildrenWithAssets(root, childMap, assetsMap);
                })
                .collect(Collectors.toList());
    }

    private void setChildrenWithAssets(Catalog catalog, Map<Long, List<Catalog>> childMap, Map<Long, List<Assets>> assetsMap) {
        List<Assets> assets = assetsMap.getOrDefault(catalog.getId(), Collections.emptyList());
        catalog.setAssets(assets);
        List<Catalog> children = childMap.getOrDefault(catalog.getId(), Collections.emptyList());
        catalog.setChildCatalog(children);

        // 递归设置子目录的子目录和资源
        for (Catalog child : children) {
            setChildrenWithAssets(child, childMap, assetsMap);
        }
    }

    @Override
    public Catalog getById(Long id) {
        return catalogDao.getById(id);
    }

    @Override
    public List<Catalog> getByParentId(Long parentId) {
        return catalogDao.getByParentId(parentId);
    }

    @Override
    public List<Catalog> getByLevel(Integer level) {
        return catalogDao.getByLevel(level);
    }

    @Override
    public Long insert(Catalog catalog) {
        // 调用catalogDao的insert方法将目录对象插入数据库
        int result = catalogDao.insert(catalog);
        if (result == 1) {
            // 获取新生成的ID
            Long newId = catalog.getId();
            System.out.println("New catalog ID: " + newId);
            // 返回新生成的ID给调用者
            return newId;
        } else {
            // 如果插入失败，返回-1作为错误标识
            return Long.valueOf(-1);
        }
    }


    @Override
    public int update(Catalog catalog) {
        return catalogDao.update(catalog);
    }

    @Override
    @Transactional
    public int delete(Long id) {
        List<Catalog> childrenCatalogs = catalogDao.getAllByParentId(id);
        if (childrenCatalogs == null || childrenCatalogs.isEmpty()) {
            //没有子目录，只删除自己
            assetsMapper.deleteByCatalogId(id);
            return catalogDao.delete(id);
        }
        List<Long> ids = childrenCatalogs.stream()
                .map(Catalog::getId)
                .collect(Collectors.toList());
        //有子目录，将自己的id加入列表，批量删除
        ids.add(id);
        assetsMapper.deleteManyByCatalogId(ids);
        return catalogDao.deleteMany(ids);
    }


    @Override
    @Transactional
    public int deleteMany(List<Long> ids) {
        return catalogDao.deleteMany(ids);
    }


    @Override
    @Transactional
    public Boolean cloneCatalog(Long id, Long bandId) {
        Catalog rootCatalog = catalogDao.getById(id);
        if (rootCatalog == null) {
            return false;
        }
        // 只有level为0才是作为模板的根目录
        if (rootCatalog.getLevel() != 0) {
            return false;
        } else {
            try {
                List<Catalog> childCatalogs = catalogDao.getByParentId(rootCatalog.getId());
                rootCatalog.setId(null);
                rootCatalog.setLevel(1);
                rootCatalog.setBandId(bandId);
                Long parentId = insert(rootCatalog);
                if (childCatalogs == null || childCatalogs.isEmpty()) {
                    return true;
                }
                cloneChildCatalog(parentId, bandId, childCatalogs);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }

    private void cloneChildCatalog(Long parentId, Long bandId, List<Catalog> catalogs) {
        for (Catalog catalog : catalogs) {
            List<Catalog> childCatalogs = catalogDao.getByParentId(catalog.getId());
            catalog.setId(null);
            catalog.setBandId(bandId);
            catalog.setParentId(parentId != null ? parentId : null);
            Long newParentId = insert(catalog);
            if (childCatalogs == null || childCatalogs.isEmpty()) {
                continue;
            }
            cloneChildCatalog(newParentId, bandId, childCatalogs);
        }
    }

    @Override
    public HashMap<String, Long> calculateNumberByCatalogId(Long catalogId) {
        final int size = assetsMapper.getAssetsByCatalogId(catalogId).size();
        Long catalogNumber = catalogDao.getAllCountByParentId(catalogId);
        Long assetNumber = catalogDao.getAllAssetCountByParentId(catalogId);
        Long emptyAssetCatalogNumber = catalogDao.getEmptyAssetCountByParentId(catalogId);

        HashMap<String, Long> map = new HashMap<>();
        map.put("catalogNumber", catalogNumber);
        map.put("emptyCatalogNumber", emptyAssetCatalogNumber);
        map.put("fileNumber", assetNumber + size);
        return map;
    }


    public Catalog findCatalogById(List<Catalog> catalogList, Long id) {

        for (Catalog child : catalogList) {
            if (child.getId().equals(id)) {
                return child;
            }
            if (child.getChildCatalog() != null) {
                Catalog foundCatalog = findCatalogById(child.getChildCatalog(), id);
                if (foundCatalog != null) {
                    return foundCatalog;
                }
            }
        }
        return null;
    }

    @Override
    public HashMap<String, Long> calculateNumberByBandId(Long bandId, Long schoolId) {
        Long catalogCount = catalogDao.getCatalogCountByBandId(bandId, schoolId);
        Long emptyCatalogCount = catalogDao.getEmptyCatalogCountByBandId(bandId, schoolId);
        Long assetCount = catalogDao.getAssetCountByBandId(bandId, schoolId);
        HashMap<String, Long> map = new HashMap<>();
        map.put("catalogNumber", catalogCount);
        map.put("emptyCatalogNumber", emptyCatalogCount);
        map.put("fileNumber", assetCount);
        return map;
    }


}